package com.atguigu.lease.web.admin.custom.converter;

import com.atguigu.lease.model.enums.BaseEnum;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

//Todo 不理解这里, 后面需要再学习
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        // 添加通用的枚举转换器
        registry.addConverterFactory(new StringToBaseEnumConverterFactory());
    }

    /**
     * 通用枚举转换器工厂，可以处理所有实现了BaseEnum接口的枚举类
     */
    private static class StringToBaseEnumConverterFactory implements ConverterFactory<String, BaseEnum> {

        @Override
        @SuppressWarnings("unchecked")
        public <T extends BaseEnum> Converter<String, T> getConverter(Class<T> targetType) {
            if (!targetType.isEnum()) {
                throw new IllegalArgumentException("目标类型必须是枚举类型: " + targetType);
            }
            return new StringToBaseEnumConverter<>((Class<T>) targetType);
        }



        /**
         * 将字符串转换为对应的枚举类型
         * @param <T> 目标枚举类型
         */
        private static class StringToBaseEnumConverter<T extends BaseEnum> implements Converter<String, T> {
            private final Class<T> enumType;

            public StringToBaseEnumConverter(Class<T> enumType) {
                this.enumType = enumType;
            }

            @Override
            public T convert(String source) {
                if (source == null || source.trim().isEmpty()) {
                    return null;
                }

                source = source.trim();

                // 尝试将输入转换为整数
                try {
                    Integer code = Integer.parseInt(source);
                    T enumInstance = convertByCode(code);
                    if (enumInstance != null) {
                        return enumInstance;
                    }
                } catch (NumberFormatException ignored) {
                    // 忽略异常，继续尝试按名称匹配
                }

                // 如果按编码没找到或不是数字，尝试按名称匹配
                return convertByName(source);
            }

            /**
             * 根据枚举编码查找对应的枚举实例
             */
            private T convertByCode(Integer code) {
                T[] enumConstants = enumType.getEnumConstants();
                for (T e : enumConstants) {
                    if (e.getCode().equals(code)) {
                        return e;
                    }
                }
                return null;
            }

            /**
             * 根据枚举名称查找对应的枚举实例
             */
            @SuppressWarnings("unchecked")
            private T convertByName(String name) {
                T[] enumConstants = enumType.getEnumConstants();

                // 先尝试匹配getName()返回的名称
                for (T e : enumConstants) {
                    if (e.getName().equalsIgnoreCase(name)) {
                        return e;
                    }
                }

                // 再尝试匹配枚举常量名
                try {
                    // 这里需要正确处理泛型
                    return (T) Enum.valueOf((Class)enumType, name.toUpperCase());
                } catch (IllegalArgumentException ex) {
                    // 如果都匹配不上，返回null
                    return null;
                }
            }
        }
    }
}